package com.ttl.ttldemo.config;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * rabbitmq本身不支持延迟消息
 * 但是根据死信队列的特点可以为一个普通队列发送消息，设置过期时间 ， 只要不接受不处理这条消息，者条消息就会定时过期发送到死信队列中
 * 将这个死信队列视为业务目标队列进行业务处理则可以看似为 延迟消息
 */
@Configuration
public class DirectConfig {

    public static final String TTL_QUEUE="ttl_queue";
    public static final String TTL_EXCHANGE="ttl_exchange";
    public static final String TTL_ROUTE_KEY="ttl_route_key";


    public static final String TLL_DEAD_QUEUE="tll_dead_queue";
    public static final String TTL_DEAD_EXCHANGE="tll_dead_exchange";

    public static final String TTL_DEAD_ROUTE_KEY="ttl_dead_route_key";

    /**
     * 创建队列
     */
    @Bean
    public Queue queue(){
        Map<String, Object> arguments =new HashMap<>();
        //设置对列的过期时间为20秒 , 延迟消息方式二，给队列设置消息延迟 ， 但是这个队列里面的呢搜有消息都会延迟相同的时间
        //测试的时候只用一个，另一个注释 ， 如果两个都用则按时间短的延迟消息
        arguments.put("x-message-ttl",20000);
        // 重点：：设置这两个参数
        arguments.put("x-dead-letter-exchange",TTL_DEAD_EXCHANGE); //设置对列的死信交换机
        arguments.put("x-dead-letter-routing-key",TTL_DEAD_ROUTE_KEY); //设置死信路由key，要和死信交换机和死信队列绑定key一模一样
        return new Queue(TTL_QUEUE,false,false,true,arguments);
    }

    @Bean
    public Queue queueTTL(){
        return new Queue(TLL_DEAD_QUEUE,false,false,true);
    }

    /**
     * 创建的交换机
     */
    @Bean
    public DirectExchange DirectExchange(){
        //同理队列，建造者模式也可以在后面加很多属性
        return ExchangeBuilder.directExchange(TTL_EXCHANGE).autoDelete().build();
    }
    @Bean
    public DirectExchange DirectExchangeTTL(){
        //同理队列，建造者模式也可以在后面加很多属性
        return ExchangeBuilder.directExchange(TTL_DEAD_EXCHANGE).autoDelete().build();
    }

    /**
     * 绑定关系
     */
    @Bean
    public Binding bind(){
        return BindingBuilder.bind(queue()).to(DirectExchange()).with(TTL_ROUTE_KEY);
    }
    @Bean
    public Binding bindTTL(){
        return BindingBuilder.bind(queueTTL()).to(DirectExchangeTTL()).with(TTL_DEAD_ROUTE_KEY);
    }

}
